package cn.sdhuijin.service;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.sdhuijin.dao.DeductionDao;
import cn.sdhuijin.dao.StandardDao;
import cn.sdhuijin.dao.StandardFolderDao;
import cn.sdhuijin.dao.StandardItemDao;
import cn.sdhuijin.dao.TargetDao;
import cn.sdhuijin.model.Deduction;
import cn.sdhuijin.model.DeductionPdf;
import cn.sdhuijin.model.Standard;
import cn.sdhuijin.model.StandardFolder;
import cn.sdhuijin.model.StandardItem;
import cn.sdhuijin.model.Target;
import cn.sdhuijin.utils.CommonUtil;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

/**
 * @author houyc
 * @version 创建时间：2015-05-08
 */

@Service
@Transactional
public class PDFServiceImpl implements PDFService {

	@Inject
	private TargetDao targetDao;
	@Inject
	private StandardDao standardDao;
	@Inject
	private StandardFolderDao standardFolderDao;
	@Inject
	private StandardItemDao standardItemDao;
	@Inject
	private EntityManagerFactory entityManagerFactory;
	@Inject
	private DeductionDao deductionDao;

	/**
	 * 通过考核方案ID查询考核明细列表
	 */
	@Override
	public boolean exportStandardPdfByID(Long id) throws Exception {
		boolean result = false;
		// 新建PDF文档，设置为A4和页面边距
		Document document = new Document(PageSize.A4, 10, 10, 10, 10);
		PdfWriter writer = PdfWriter.getInstance(document,
				new FileOutputStream("D:\\houyc.pdf"));
		document.open();
		// 考核方案名称
		String name = getStandardName(id);
		Paragraph pdfTitle = getStandardTitleParagraph(name);
		document.add(pdfTitle);
		// 考核对象
		PdfPTable targetTable = getStandardTargetPTable(id);
		document.add(targetTable);
		List<StandardFolder> folderList = standardFolderDao
				.findByStandardId(id);
		if (folderList != null) {
			for (int i = 0; i < folderList.size(); i++) {
				StandardFolder standardFolder = folderList.get(i);
				String title = standardFolder.getId() + "."
						+ standardFolder.getName() + "："
						+ standardFolder.getScore() + "(分)";
				Paragraph standardFolderTitle = getFolderTitleParagraph(title);
				document.add(standardFolderTitle);
				List<StandardItem> itemsList = standardItemDao
						.findByStandardFolderId(standardFolder.getId());
				if (itemsList != null) {
					// 建一个有4列的表格
					PdfPTable itemsTable = new PdfPTable(4);
					// 表格固定宽度
					itemsTable.setTotalWidth(800);
					// 每列固定宽度
					itemsTable.setTotalWidth(new float[] { 80, 450, 170, 100 });
					itemsTable.setHorizontalAlignment(Element.ALIGN_CENTER);
					// 添加标题列
					PdfPCell idCell = new PdfPCell(new Phrase("序号",
							setChineseFont()));
					idCell.setHorizontalAlignment(Element.ALIGN_CENTER);
					PdfPCell descCell = new PdfPCell(new Phrase("考核标准",
							setChineseFont()));
					descCell.setHorizontalAlignment(Element.ALIGN_CENTER);
					PdfPCell methodCell = new PdfPCell(new Phrase("考核方法",
							setChineseFont()));
					methodCell.setHorizontalAlignment(Element.ALIGN_CENTER);
					PdfPCell scoreCell = new PdfPCell(new Phrase("所占分值",
							setChineseFont()));
					scoreCell.setHorizontalAlignment(Element.ALIGN_CENTER);
					itemsTable.addCell(idCell);
					itemsTable.addCell(descCell);
					itemsTable.addCell(methodCell);
					itemsTable.addCell(scoreCell);
					for (int j = 0; j < itemsList.size(); j++) {
						itemsTable.addCell(new Phrase(String.valueOf(itemsList
								.get(j).getId()), setChineseFont()));
						itemsTable.addCell(new Phrase(String.valueOf(itemsList
								.get(j).getDescription()), setChineseFont()));
						itemsTable.addCell(new Phrase(String.valueOf(itemsList
								.get(j).getMethod()), setChineseFont()));
						itemsTable.addCell(new Phrase(String.valueOf(itemsList
								.get(j).getScore()), setChineseFont()));
					}
					document.add(itemsTable);
				}
			}
		}
		document.close();
		result = true;
		return result;
	}

	/**
	 * PDF章标题
	 * 
	 * @param name
	 * @return
	 */
	public Paragraph getStandardTitleParagraph(String name) {
		Paragraph paragraph = null;
		try {
			paragraph = new Paragraph(name, new Font(BaseFont.createFont(
					"simkai.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED), 24,
					Font.BOLD));
			paragraph.setSpacingAfter(10);
			paragraph.setSpacingBefore(10);
			paragraph.setAlignment(Element.ALIGN_CENTER);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return paragraph;
	}

	/**
	 * PDF章标题
	 * 
	 * @param name
	 * @return
	 */
	public Paragraph getFolderTitleParagraph(String name) {
		Paragraph paragraph = null;
		try {
			paragraph = new Paragraph(name, new Font(BaseFont.createFont(
					"simkai.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED), 16,
					Font.BOLD));
			paragraph.setSpacingAfter(10);
			paragraph.setSpacingBefore(10);
			paragraph.setAlignment(Element.ALIGN_LEFT);
			paragraph.setIndentationLeft(50);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return paragraph;
	}

	/**
	 * 查询考核方案名称，作为PDF标题
	 * 
	 * @param id
	 * @return
	 */
	public String getStandardName(Long id) {
		String name = "";
		Standard standard = null;
		try {
			standard = standardDao.findOne(id);
			if (standard != null) {
				name = standard.getName();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return name;
	}

	/**
	 * 考核对象表格
	 * 
	 * @param id
	 * @return
	 */
	public PdfPTable getStandardTargetPTable(Long id) {
		PdfPTable table = null;
		List<Target> targetList = null;
		try {
			table = new PdfPTable(2);
			targetList = targetDao.findByStandardId(id);
			if (targetList != null) {
				table.setTotalWidth(800);
				// 设置每列宽度
				table.setTotalWidth(new float[] { 80, 720 });
				PdfPCell idCell = new PdfPCell(new Phrase("序号",
						setChineseFont()));
				idCell.setHorizontalAlignment(Element.ALIGN_CENTER);
				PdfPCell targetCell = new PdfPCell(new Phrase("考核对象",
						setChineseFont()));
				targetCell.setHorizontalAlignment(Element.ALIGN_CENTER);
				table.addCell(idCell);
				table.addCell(targetCell);
				for (int i = 0; i < targetList.size(); i++) {
					table.addCell(new Phrase(String.valueOf(targetList.get(i)
							.getId()), setChineseFont()));
					table.addCell(new Phrase(getTargetName(targetList.get(i)
							.getId()), setChineseFont()));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return table;
	}

	/**
	 * 支持PDF中文输入，默认采用楷体常规
	 * 
	 * @return
	 */
	public static Font setChineseFont() {
		BaseFont bf = null;
		Font fontChinese = null;
		try {
			bf = BaseFont.createFont("simkai.ttf", BaseFont.IDENTITY_H,
					BaseFont.EMBEDDED);
			fontChinese = new Font(bf, 12, Font.NORMAL);
		} catch (DocumentException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return fontChinese;
	}

	/**
	 * 通过递归查询考核对象
	 * 
	 * @param targetId
	 * @return
	 */
	public String getTargetName(Long targetId) {
		Target target = targetDao.findOne(targetId);
		String targetName = "";
		targetName = target.getName() + targetName;
		if (target.getParent() == null) {
			return targetName;
		} else {
			return getTargetName(target.getParent().getId()) + targetName;
		}
	}

	/**
	 * 导出方案具体扣分项
	 */
	@Override
	public boolean exportDeductionPdfByID(Long id) throws Exception {

		boolean result = false;
		// 新建PDF文档，设置为A4和页面边距
		Document document = new Document(PageSize.A4, 10, 10, 10, 10);
		PdfWriter writer = PdfWriter.getInstance(document,
				new FileOutputStream("D:\\deduction.pdf"));
		document.open();
		// 考核方案名称
		String name = getStandardName(id);
		Paragraph pdfTitle = getStandardTitleParagraph(name);
		document.add(pdfTitle);
		// 考核对象
		List<DeductionPdf> pdfList = getDeductionPdfList(id);
		if (pdfList != null) {
			for (int i = 0; i < pdfList.size(); i++) {
				DeductionPdf deductionPdf = pdfList.get(i);
				String title = (i + 1) + "." + deductionPdf.getTargetName()
						+ "：" + deductionPdf.getSumScore() + "(分)";
				Paragraph standardFolderTitle = getFolderTitleParagraph(title);
				document.add(standardFolderTitle);
				List<Deduction> itemList = deductionDao.findByTargetId(Long
						.valueOf(deductionPdf.getTargetId()));
				if (itemList != null) {
					// 建一个有4列的表格
					PdfPTable itemsTable = new PdfPTable(6);
					// 表格固定宽度
					itemsTable.setTotalWidth(800);
					// 每列固定宽度
					itemsTable.setTotalWidth(new float[] { 70, 120, 80, 320,
							100, 110 });
					itemsTable.setHorizontalAlignment(Element.ALIGN_CENTER);
					// 添加标题列
					PdfPCell idCell = new PdfPCell(new Phrase("序号",
							setChineseFont()));
					idCell.setHorizontalAlignment(Element.ALIGN_CENTER);
					PdfPCell descCell = new PdfPCell(new Phrase("考核项目",
							setChineseFont()));
					descCell.setHorizontalAlignment(Element.ALIGN_CENTER);
					PdfPCell scoreCell = new PdfPCell(new Phrase("得分",
							setChineseFont()));
					scoreCell.setHorizontalAlignment(Element.ALIGN_CENTER);
					PdfPCell remarksCell = new PdfPCell(new Phrase("说明",
							setChineseFont()));
					remarksCell.setHorizontalAlignment(Element.ALIGN_CENTER);
					PdfPCell operatorCell = new PdfPCell(new Phrase("评定人",
							setChineseFont()));
					operatorCell.setHorizontalAlignment(Element.ALIGN_CENTER);
					PdfPCell dateCell = new PdfPCell(new Phrase("评定日期",
							setChineseFont()));
					dateCell.setHorizontalAlignment(Element.ALIGN_CENTER);
					itemsTable.addCell(idCell);
					itemsTable.addCell(descCell);
					itemsTable.addCell(scoreCell);
					itemsTable.addCell(remarksCell);
					itemsTable.addCell(operatorCell);
					itemsTable.addCell(dateCell);
					for (int j = 0; j < itemList.size(); j++) {
						itemsTable.addCell(new Phrase(String.valueOf(itemList
								.get(j).getId()), setChineseFont()));
						itemsTable.addCell(new Phrase(String.valueOf(itemList
								.get(j).getStandardItem().getStandardFolder().getName()),
								setChineseFont()));
						itemsTable.addCell(new Phrase(String.valueOf(itemList
								.get(j).getScore()), setChineseFont()));
						itemsTable.addCell(new Phrase(String.valueOf(itemList
								.get(j).getDescription()), setChineseFont()));
						itemsTable.addCell(new Phrase(String.valueOf(itemList
								.get(j).getOperater()), setChineseFont()));
						itemsTable.addCell(new Phrase(CommonUtil.formatDateToYmdString(itemList
								.get(j).getDate()), setChineseFont()));
					}
					document.add(itemsTable);
				}
			}
		}
		document.close();
		result = true;
		return result;

	}

	public List<DeductionPdf> getDeductionPdfList(Long id) {
		EntityManager entityManager = null;
		Query query = null;
		List<DeductionPdf> pdfList = new ArrayList<DeductionPdf>();
		try {
			entityManager = entityManagerFactory.createEntityManager();
			query = entityManager
					.createNativeQuery("SELECT D.target_id AS targetId,"
							+ "S.name AS standardName,"
							+ "T.name AS targetName,"
							+ "SUM(D.score) AS sumScore " + "FROM deduction D "
							+ "LEFT JOIN standard S "
							+ "ON D.standard_id = S.id "
							+ "LEFT JOIN target T " + "ON D.target_id = T.id "
							+ "WHERE D.standard_id = ? "
							+ "AND D.isDeleted = 0 " + "GROUP BY D.target_id "
							+ "ORDER BY sumScore DESC");
			query.setParameter(1, id);
			List list = query.getResultList();
			if (list != null) {
				for (int i = 0; i < list.size(); i++) {
					DeductionPdf pdfItem = new DeductionPdf();
					Object[] objs = (Object[]) list.get(i);
					pdfItem.setTargetId(objs[0].toString());
					pdfItem.setStandardName(objs[1].toString());
					pdfItem.setTargetName(objs[2].toString());
					pdfItem.setSumScore(objs[3].toString());
					pdfList.add(pdfItem);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (entityManager != null) {
				entityManager.close();
			}
		}
		return pdfList;
	}
}
